package ig.metrica.rentabilidad;

import ig.finanzas.*;
import ig.metrica.ejb.html.GenerarHTML;
import ig.metrica.riesgo.ZonaDTO;
import java.rmi.RemoteException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import ig.util.ConexionServer;
import ig.util.ejb.IGSessionBean;
import ig.util.excepciones.DatoInvalidoExcepcion;
import ig.util.excepciones.LogicaExcepcion;
import java.util.*;

public class CalculoRentabilidadBean extends IGSessionBean {

    private GenerarHTML generarHTML = null;
    private Collection<ZonaDTO> collection = new ArrayList();

    public void setGenerarHTML(GenerarHTML generarHTML) {
        this.generarHTML = generarHTML;
    }

    private MonedaBean getMoneda(MonedaPK monedaPK) throws NamingException, Exception{
        return new MonedaBean().ejbFindByPrimaryKey(monedaPK);
    }

    /**
     * Efectua el analisis de rentabilidad
     *
     * @param fechaInicio
     * @param fechaFin
     * @throws DatoInvalidoExcepcion Si alguna de las fechas suministradas es
     * nula, o si la fecha final es menor que la inicial.
     * @throws SQLException Si se presento un error al conectarse u obtener los
     * datos de la base de datos.
     * @throws NamingException Si se presento un error con JNDI.
     * @throws FinderException Si no se pueden encontrar los objetos en el
     * servidor de aplicaciones.
     * @throws LogicaExcepcion Si no hay valores historicos para las monedas
     * suficientes para establecer un valor vigente.
     */
    public void efectuarCalculo(Date fechaInicio, Date fechaFin, int mTipoValoracion) throws NamingException, SQLException, Exception, DatoInvalidoExcepcion, LogicaExcepcion {

        if (fechaInicio == null) {
            generarHTML.println("La fecha de inicio es nula.");
            throw new DatoInvalidoExcepcion("La fecha de inicio es nula.");
        }

        if (fechaFin == null) {
            generarHTML.println("La fecha de fin es nula.");
            throw new DatoInvalidoExcepcion("La fecha de fin es nula.");
        }

        if (fechaFin.getTime() <= fechaInicio.getTime()) {
            generarHTML.println("La fecha final es menor que la inicial.");
            throw new DatoInvalidoExcepcion("La fecha final es menor que la inicial.");
        }

        Properties prop = new Properties();
        prop.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        String Sockec = new ConexionServer().getSocketServer();
        prop.put(Context.PROVIDER_URL, Sockec);


        conn = getConexion("METRICADB");
        List contratos;

        Iterator i;

        //Se borra la informacion de las tablas donde se va a almacenar la informacion.
        //Statement stmt1 = conn.createStatement();
        //stmt1.executeUpdate("DELETE FROM CALCULOSRENTABILIDADCONTRATOS");
        //if (stmt1!=null)
        //	stmt1.close();

        if (mTipoValoracion == 1) {
//                    pstmt1 = conn.prepareStatement("SELECT VALORAFECHA1, VALORAFECHA2 FROM ADICIONALESCONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");
            pstmt1 = conn.prepareStatement("SELECT VALORAFECHA1, VALORAFECHA2 FROM ADICONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");
        } else {
//                    pstmt1 = conn.prepareStatement("SELECT VALORATIRFECHA1 AS VALORAFECHA1, VALORATIRFECHA2 AS VALORAFECHA2 FROM ADICIONALESCONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");                    
            pstmt1 = conn.prepareStatement("SELECT VALORATIRFECHA1 AS VALORAFECHA1, VALORATIRFECHA2 AS VALORAFECHA2 FROM ADICONTRATOSRENTABILIDAD  WHERE IDCONTRATO=?");
        }



//		pstmt1 = conn.prepareStatement("SELECT VALORAFECHA1, VALORAFECHA2 FROM ADICIONALESCONTRATOSRENTABILIDAD WHERE IDCONTRATO=?");
        //pstmt2 = conn.prepareStatement("INSERT INTO CALCULOSRENTABILIDADCONTRATOS VALUES(?,?,?,?,?,?)");

        InitialContext ctx = new InitialContext(prop);

        /*
         * ----------------------------------------------------------------------------------------------------------------------------
         * ContratosSimples.
         */

        //ContratoSimpleHome home1 = (ContratoSimpleHome) ctx.lookup("ig.finanzas.ContratoSimple");
        //PosicionEspecieHome home2 = (PosicionEspecieHome) ctx.lookup("ig.finanzas.PosicionEspecie");
        //PosicionAccionHome home3 = (PosicionAccionHome) ctx.lookup("ig.finanzas.PosicionAccion");

        try {
            contratos = new ContratoSimpleBean().ejbFindAll();
            contratos.addAll(new PosicionEspecieBean().ejbFindAll());
            contratos.addAll(new PosicionAccionBean().ejbFindAll());
            i = contratos.iterator();
            generarHTML.println("Procesando " + contratos.size() + " Contratos");
            pstmt2 = conn.prepareStatement("INSERT INTO CALCULOSRENTABILIDADCONTRATOS VALUES(?,?,?,?)");
            while (i.hasNext()) {
                //Recorro los contratos simples
                ContratoBean contrato = (ContratoBean) i.next();
                contrato.cargarEntidad();
                ManejadorFlujos flujos = contrato.flujosEntre(fechaInicio, false, fechaFin, true);

                pstmt1.setLong(1, contrato.getPk().getIdInterna());
                ResultSet r1 = pstmt1.executeQuery();

                Double valoracionfinal = null;

                if (r1.next()) {
                    String temp = r1.getString("VALORAFECHA1");
                    Double temp1 = new Double(temp).doubleValue();
                    if (temp1 != 0) {
                        flujos.adicionarFlujo(new Flujo(fechaInicio, new Double(temp).doubleValue() * -1, 0, 0, true, false));
                    }

                    temp = r1.getString("VALORAFECHA2");
                    Double temp2 = new Double(temp).doubleValue();
                    if (temp2 != 0) {
                        flujos.adicionarFlujo(new Flujo(fechaFin, new Double(temp).doubleValue(), 0, 0, true, false));
//						valoracionfinal = new Double(temp);
                    }
                    //}//ojo cambiada por la que esta despue del execute de la linea 182

                    if (flujos.numeroFlujos() == 0) {
                        continue;
                    }

                    if (valoracionfinal == null) {
                        valoracionfinal = new Double(flujos.sumaFlujosPositivos());
                    }

                    int numdias = (int) ((flujos.fechaUltimoFlujo().getTime() - flujos.fechaPrimerFlujo().getTime()) / (24 * 60 * 60 * 1000));
                    double tirFlujoCaja = flujos.tir();
                    MonedaBean moneda = getMoneda(contrato.getMonedaPK());
                    double cambio = moneda.obtenerValorVigenteA(flujos.fechaUltimoFlujo());
                    //				double valoracion = valoracionfinal.doubleValue() * cambio ;
                    double valoracion = valoracionfinal.doubleValue();

                    pstmt2.setLong(1, contrato.getPk().getIdInterna());
                    pstmt2.setDouble(2, tirFlujoCaja);
                    pstmt2.setInt(3, numdias);
                    pstmt2.setDouble(4, valoracion);
                    pstmt2.executeUpdate();
                    pstmt2.clearParameters();
                }
            }
//                } catch (SQLException e) {
//                    e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        closeAll();
    }

    public void closeAll() {
        try {
            if (conn != null && !conn.isClosed()) {
                conn.close();
            }
        } catch (SQLException e) {
        }
        try {
            if (pstmt1 != null) {
                pstmt1.close();
            }
        } catch (Exception e) {
        }
        try {
            if (pstmt2 != null) {
                pstmt2.close();
            }
        } catch (Exception e) {
        }
        try {
            if (pstmt3 != null) {
                pstmt3.close();
            }
        } catch (Exception e) {
        }
        try {
            if (pstmt4 != null) {
                pstmt4.close();
            }
        } catch (Exception e) {
        }
        try {
            if (pstmt5 != null) {
                pstmt5.close();
            }
        } catch (Exception e) {
        }
    }

    public void setZonas(Collection<ZonaDTO> collection) {
        this.collection = collection;
    }
}